/**
 * 请求工具
 * 说明: 使用了luch-request作为基础
 * 详细使用可以查看 https://www.quanzhan.co/luch-request/
 */
import Request from "luch-request";
import { api } from "../config";
import { toast } from "@/tuniao-ui/utils";
import { navPage, navLogin } from "@/tuniao-ui/utils";
import { useUserStoreWidthOut } from "@/tuniao-ui/store/user";
import { getStorage, setStorage, removeStorage } from "@/tuniao-ui/utils";
import {
  ACCESS_TOKEN,
  REFRESH_ACCESS_TOKEN,
  CURRENT_USER,
} from "@/tuniao-ui/store/mutation-types";

export type RequestType<T = any> = {
  code: number;
  result: T;
  message: string;
};

export default class Http {
  static http: Request = new Request();

  static request<T>(opt: any): Promise<T> {
    if (opt.needToken) {
      const that = this;
      // 请求前 判断token
      const userStore = useUserStoreWidthOut();
      const token = getStorage(ACCESS_TOKEN);
      // 如果不存在 说明过期了
      if (!token) {
        const refreshToken = getStorage(REFRESH_ACCESS_TOKEN);
        // 刷新token还存在，还能刷新
        if (refreshToken) {
          return new Promise((resolve, reject) => {
            userStore.RefreshToken().then(() => {
              // 本次请求放在刷新token之后
              that.service(opt).then(resolve).catch(reject);
            });
          });
        }
        
        navLogin();
        return Promise.reject("请登录");
        
      } else {
        return this.service(opt);
      }
    } else {
      return this.service(opt);
    }
  }

  /**
   * 实际发送请求
   * @param opt
   * @returns
   */
  static service<T>(opt: any): Promise<T> {
    const options = {
      method: opt.method, // 请求方法必须大写
      url: opt.url,
      data: opt.data,
      params: opt.params,
      // 注：如果局部custom与全局custom有同名属性，则后面的属性会覆盖前面的属性，相当于Object.assign(全局，局部)
      custom: {
        isJson: opt.isJson,
        needToken: opt.needToken,
      }, // 自定义参数
    };
    return new Promise((resolve, reject) => {
      Http.http
        .request<T>(options)
        .then((res) => {
          // 判断以2（2xx)开头的状态码为正确
          // 异常不要返回到回调中，就在request中处理
          let code = res.statusCode.toString();
          let stateChar = code.charAt(0);
          if (stateChar === "2") {
            if (res.data.code === 401) {
              // 跳转登录页
              console.log("需要登录, 跳转登录页");
              let routes = getCurrentPages();
              let toUrl = routes[routes.length - 1].$page.fullPath; //获取当前页面
              //console.log("toUrl", toUrl);
              navPage("/pages/mine/login?toUrl=" + toUrl);
            } else {
              resolve(res.data);
            }
          } else {
            Http.handleRequestError(res);
            reject(res);
          }
        })
        .catch((err) => {
          toast({
            icon: "none",
            title: "请求失败",
          });
          Http.handleRequestError(err);
          reject(err);
        });
    });
  }

  static handleRequestError(err: any) {
    console.error("[http]请求失败", err);
  }
}

Http.http.interceptors.request.use(
  (config) => {
    config.baseURL = api.base;

    //如果需要json传递方式
    if (config.custom?.isJson) {
      config.header = {
        ...config.header,
        "Content-Type": "application/json;charset=UTF-8",
      };
    } else {
      config.header = {
        ...config.header,
        "Content-Type": "application/x-www-form-urlencoded",
      };
    }

    // 请求前 判断token
    if (config.custom?.needToken) {
      const token = getStorage(ACCESS_TOKEN);
      if (token) {
        config.header["Authorization"] = `Bearer ${token}`;
      }
    }

    // if (config.custom?.needToken) {
    //   // 请求前 判断token
    //   const userStore = useUserStoreWidthOut();
    //   const token = getStorage(ACCESS_TOKEN);
    //   console.log('拦截前token',token);
    //   // 如果不存在 说明过期了
    //   if (!token) {
    //     const refreshToken = getStorage(REFRESH_ACCESS_TOKEN);
    //     // 刷新token还存在，还能刷新
    //     if (refreshToken) {
    //       userStore.RefreshToken().then(() => {
    //         console.log("重新请求",config)
    //         // 本次请求放在刷新token之后
    //         Http.request<RequestType>(config);
    //       });
    //       // 取消本次请求
    //       return Promise.reject(config);
    //     }
    //   } else {
    //     config.header["Authorization"] = `Bearer ${token}`;
    //   }
    // }

    return config;
  },
  (config) => {
    return Promise.reject(config);
  }
);
